﻿namespace WebPacker.Configuration
{
	using System;
	using System.Reflection;
	using System.Text;
	using NXml.Serialization.TypeResolvers;
	using WebPacker.Filters;
	using WebPacker.Providers;
	using WebPacker.VersionGenerators;

	public class WebPackerTypeResolver : XmlTypeResolver
	{
		private static readonly string assemblyName = Assembly.GetExecutingAssembly().GetName().ToString();

		public override Type ResolveTypeName(Type expectedType, string typeName)
		{
			if (typeName != null && typeName.IndexOf(',') == -1 && !typeName.StartsWith(expectedType.Namespace))
			{
				if (expectedType == typeof(IFilter) || expectedType == typeof(IPackProvider) || expectedType == typeof(IVersionGenerator))
				{
					var builder = new StringBuilder();
					builder.Append(expectedType.Namespace).Append('.');

					if (char.IsLower(typeName[0]))
					{
						builder.Append(char.ToUpper(typeName[0])).Append(typeName, 1, typeName.Length - 1);
					}
					else
					{
						builder.Append(typeName);
					}

					if (expectedType != typeof(IFilter) && typeName.Length > 1)
					{
						var postfix = expectedType.Name.Substring(1);

						if (!typeName.EndsWith(postfix))
						{
							builder.Append(postfix);
						}
					}

					builder.Append(", ").Append(assemblyName);

					var type = Type.GetType(builder.ToString(), false, false);

					if (type != null && type.GetInterface(expectedType.FullName) != null)
					{
						return type;
					}
				}
			}

			return base.ResolveTypeName(expectedType, typeName);
		}
	}
}